home *** CD-ROM | disk | FTP | other *** search
/ Aminet 38 / Aminet 38 (2000)(Schatztruhe)[!][Aug 2000].iso / Aminet / dev / misc / intlist.lha / IntList / Source / ToggleLED.asm < prev   
Encoding:
Assembly Source File  |  1997-11-09  |  5.4 KB  |  246 lines

  1. *************************************
  2. **
  3. ** Copyright © 1997 Jörg van de Loo
  4. **            Hövel 15
  5. **            47559 Kranenburg
  6. **            Germany
  7. *
  8. ** Example stuff for the use of one of the two CIA-B timers - in mind
  9. ** the RKM Hardware Reference Manual from 1989, Appendix F, page 317 - 333.
  10. *
  11. ** By the way: This code is reentrant.
  12. *
  13.  
  14.  
  15.     IFD    __G2
  16.         MACHINE    MC68000
  17.         OPT    OW-
  18.         OUTPUT    RAM:ToggleLED
  19.     ENDC
  20.  
  21.     include    exec/exec_lib.i
  22.     include    exec/interrupts.i
  23.     include    exec/execbase.i
  24.  
  25.     include    dos/dos.i
  26.     include    dos/dosextens.i
  27.  
  28.     include    resources/cia_lib.i
  29.  
  30.     include    hardware/cia.i
  31.  
  32.  
  33.    STRUCTURE    __Table,0
  34.     APTR    _SysBase
  35.     APTR    _CIABBase
  36.     APTR    _ThisTask
  37.  
  38.     ULONG    _Timer                CIA-B Timer A (#0) or B (#1)
  39.     ULONG    _PAL_NTSC            PAL (#0) or NTSC (#2) machine
  40.     ULONG    _Counter
  41.  
  42.     STRUCT    _IRQStruct,IS_SIZE        CIA-B interrupt structure
  43.     STRUCT    _IRQCause,IS_SIZE        By Cause() required one
  44.  
  45.     ALIGNLONG
  46.     LABEL    tb_SIZEOF
  47.  
  48.  
  49. _ciaa    equ    $BFE001
  50. _ciab    equ    $BFD000
  51.  
  52.  
  53. _main
  54.     lea    -tb_SIZEOF(sp),sp        Make some room on stack (for data area)
  55.     movea.l    sp,A4                Store address data area into processor register A4
  56.  
  57.     movea.l    4.w,A6                Get Exec base
  58.     move.l    A6,_SysBase(A4)
  59.  
  60.  
  61.     suba.l    A1,A1
  62.     jsr    _LVOFindTask(A6)
  63.     move.l    D0,_ThisTask(A4)        Store address of own process structure
  64.  
  65.  
  66.     cmpi.b    #50,PowerSupplyFrequency(A6)    Which power frequency?
  67.     bne.s    _NTSC
  68.  
  69.     clr.l    _PAL_NTSC(A4)            It's PAL
  70.     bra.s    _OpenResource
  71.  
  72. _NTSC
  73.     move.l    #2,_PAL_NTSC(A4)        It's NTSC
  74.  
  75.  
  76. _OpenResource
  77.     lea    _CIABName(pc),A1
  78.     moveq    #0,D0                Any version
  79.     jsr    _LVOOpenResource(A6)        Open it...
  80.     move.l    D0,_CIABBase(A4)
  81.     beq.w    _ErrorOpenResource
  82.  
  83. *
  84. ** Set up CIA-B interrupt structure
  85. *
  86.     lea    _IRQStruct(A4),A0        Initialize IRQ structure I
  87.  
  88.     clr.l    LN_PRED(A0)            Not really required because the Resource
  89.     clr.l    LN_SUCC(A0)            will overwrite it with its own settings
  90.  
  91.     move.b    #NT_INTERRUPT,LN_TYPE(A0)
  92.     move.b    #-32,LN_PRI(A0)
  93.  
  94.     move.l    A4,IS_DATA(A0)
  95.  
  96.     lea    _IRQCode(pc),A1
  97.     move.l    A1,IS_CODE(A0)
  98.  
  99.     lea    _IRQName(pc),A1
  100.     move.l    A1,LN_NAME(A0)
  101.  
  102. *
  103. ** Set up Cause() interrupt structure
  104. *
  105.     lea    _IRQCause(A4),A0        Initialize IRQ structure II
  106.  
  107.     clr.l    LN_PRED(A0)            Not really required - these two are
  108.     clr.l    LN_SUCC(A0)            dynamically changed by Exec
  109.  
  110.     move.b    #NT_UNKNOWN,LN_TYPE(A0)        Type should be un-known - type assigned by Exec!
  111.     move.b    #-32,LN_PRI(A0)            Only -32, -16, 0, +16 and +32 supported!
  112.  
  113.     move.l    A4,IS_DATA(A0)
  114.  
  115.     lea    _IRQCauseCode(pc),A1
  116.     move.l    A1,IS_CODE(A0)
  117.  
  118.     lea    _IRQName(pc),A1
  119.     move.l    A1,LN_NAME(A0)
  120.  
  121. *
  122. ** Since the data area is located on the stack and we don't know which values
  123. ** the datas contain since they are uninitialized, and a call to AddICRVector
  124. ** causes immediately the interrupt code to be started and we also avoid a
  125. ** Disable() call, we have to initialize _Counter here:
  126. *
  127.     clr.l    _Counter(A4)
  128.  
  129.  
  130. *
  131. ** Attempt to start one of the CIA-B timer interrupts...
  132. *
  133.     moveq    #0,D2                Start with Timer A
  134.     movea.l    _CIABBase(A4),A6
  135. _try
  136.     lea    _IRQStruct(A4),A1        IRQ to execute (immediately)
  137.     move.l    D2,D0                Timer (which one?)
  138.     jsr    _LVOAddICRVector(A6)
  139.     tst.l    D0
  140.     beq.s    _GotIRQ                If the interrupt is free
  141.  
  142.     addq.b    #1,D2                Next timer
  143.     cmpi.b    #2,D2                Timer C?
  144.     beq.w    _ErrorTimer            Timer C does not exist!
  145.     bra.s    _try                Else try Timer B
  146.  
  147. _GotIRQ
  148.     move.l    D2,_Timer(A4)            Save indicator for later (0 = Timer A, 1 = Timer B)
  149.  
  150.     lea    _ciab,A0            CIA-B hardware address ($BFD000)
  151.  
  152.     move.l    _PAL_NTSC(A4),D0        0 or 2
  153.     lea    _PAL_NTSC_Times(pc),A1
  154.     move.w    0(A1,D0.l),D0            PAL time or NTSC time value to delay between each occurring
  155.  
  156.     tst.l    _Timer(A4)            0 or 1
  157.     bne.s    _TimerB                1 = Timer B
  158.  
  159. _TimerA
  160.     move.b    ciacra(A0),D1            Control register Timer A
  161.     andi.b    #%10000000,D1            Select mode (bit 7 currently unused)
  162.     ori.b    #1,D1                Set Timer A to start
  163.     move.b    D1,ciacra(A0)
  164.     move.b    #$81,ciaicr(A0)            Enable Timer A
  165.  
  166.     move.b    D0,ciatalo(A0)            Write delay time into registers
  167.     lsr.w    #8,D0
  168.     move.b    D0,ciatahi(A0)
  169.     bra.s    _ok                Done
  170.  
  171. _TimerB
  172.     move.b    ciacrb(A0),D1            Control register Timer B
  173.     andi.b    #%10000000,D1            Select mode
  174.     ori.b    #1,D1                Set Timer B to start
  175.     move.b    D1,ciacrb(A0)
  176.     move.b    #$82,ciaicr(A0)            Enable Timer B
  177.  
  178.     move.b    D0,ciatblo(A0)            Write delay time into registers
  179.     lsr.w    #8,D0
  180.     move.b    D0,ciatbhi(A0)
  181.  
  182. _ok
  183. *    btst    #CIAB_GAMEPORT0,_ciaa        Left mouse button (a busy loop - a absolute tabu)
  184. *    bne.s    _ok                - so we use the following construct:
  185.  
  186.     move.l    #SIGBREAKF_CTRL_C,D0        Wait for a control-c signal, when pressed,
  187.     movea.l    _SysBase(A4),A6            awake us,
  188.     jsr    _LVOWait(A6)            otherwise sleep...
  189.  
  190.     movea.l    _CIABBase(A4),A6
  191.     lea    _IRQStruct(A4),A1
  192.     move.l    _Timer(A4),D0
  193.     jsr    _LVORemICRVector(A6)        Stop only the CIA-B interrupt - since the other one
  194. *                        is raised by software...
  195.  
  196.     moveq    #0,D0
  197. _exit
  198.     move.l    _ThisTask(A4),A0
  199.     move.l    D0,pr_Result2(A0)        Set error code to process
  200.     lea    tb_SIZEOF(sp),sp        Restore stack
  201.     rts
  202.  
  203. _ErrorTimer
  204.     moveq    #50,D0
  205.     bra.s    _exit
  206.  
  207. _ErrorOpenResource
  208.     moveq    #100,D0
  209.     bra.s    _exit
  210.  
  211. _IRQCode    ; Through CIA-B hardware caused interrupt...
  212.     movea.l    A1,A5                IS_DATA
  213.  
  214.     lea    _IRQCause(A5),A1
  215.     movea.l    _SysBase(A5),A6
  216.     jsr    _LVOCause(A6)
  217.     moveq    #0,D0
  218.     rts
  219.  
  220. _IRQCauseCode    ; Executed each 1/50 second - regardless what for a machine and which Power supply!
  221.     movem.l    D2-D7/A2-A4/A6,-(sp)        Don't trash these...
  222.  
  223.     movea.l    A1,A5                IS_DATA
  224.  
  225.     move.l    _Counter(A5),D0
  226.     addq.l    #1,D0
  227.     cmpi.l    #50,D0
  228.     bne.s    1$
  229.  
  230.     bchg.b    #CIAB_LED,_ciaa            Toggle Power LED
  231.     moveq    #0,D0
  232. 1$
  233.     move.l    D0,_Counter(A5)
  234.  
  235.     movem.l    (sp)+,D2-D7/A2-A4/A6
  236.     moveq    #0,D0
  237.     rts
  238.  
  239. _PAL_NTSC_Times
  240.     dc.w    14187,14318    709379/50 = ~14187, 715909/50 = ~14318 (= 20,000 micro seconds = 50 times per second)
  241. _IRQName
  242.     dc.b    'LED Switcher',0
  243. _CIABName
  244.     dc.b    'ciab.resource',0
  245.  
  246.     END